package com.fenqing.comics.service.impl;

import com.fenqing.comics.annotations.CrawlerService;
import com.fenqing.comics.enums.SourceEnums;
import com.fenqing.comics.service.IAsyncService;
import com.fenqing.comics.service.ICrawlerService;
import com.fenqing.comics.utils.ApplicationContextUtils;
import com.fenqing.comics.utils.CollUtils;
import com.fenqing.comics.utils.MapUtils;
import lombok.Setter;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;

/**
 * 爬虫服务实现
 * @author fenqing
 */
@Service
@Primary
public class CrawlerServiceImpl implements ICrawlerService {

    private volatile Map<SourceEnums.Code, ICrawlerService> crawlerServiceMap;

    @Setter(onMethod_ = @Autowired)
    private IAsyncService iAsyncService;


    private ICrawlerService getCrawlerService(SourceEnums.Code code) {
        this.getCrawlerService();
        return crawlerServiceMap.get(code);
    }

    private void getCrawlerService(){
        if (crawlerServiceMap != null){
            return;
        }
        synchronized (this) {
            if (crawlerServiceMap != null) {
                return;
            }
            Map<CrawlerService, ICrawlerService> crawlerServiceMap = ApplicationContextUtils.getBeanMapByAnnotation(CrawlerService.class, ICrawlerService.class);
            this.crawlerServiceMap = MapUtils.of(
                    crawlerServiceMap,
                    CrawlerService::value
            );
        }
    }


    @SneakyThrows
    @Override
    public void start() {
        this.getCrawlerService();
        List<Future<Void>> futures = CollUtils.map(
                crawlerServiceMap.values(),
                service -> iAsyncService.asyncMethod(service::start)
        );
        for (Future<Void> future : futures) {
            future.get();
        }
    }

}
